home *** CD-ROM | disk | FTP | other *** search
- #include <LowMem.h>
- #include <A4Stuff.h>
- #include <QuickDraw.h>
- #include <Memory.h>
- #include <Resources.h>
- #include <Fonts.h>
- #include <Dialogs.h>
- #include <QDOffscreen.h>
- #include <string.h>
- #include <stdio.h>
- #include <Timer.h>
-
- #define SIMPLE 0
-
- #define PreserveFlags(x, y) ((x & 0xC000) | (y & 0x3FFF))
-
- #define crsrBase 0x898
-
- enum {
- uppA5Info = kCStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long)))
- | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))
- };
-
- enum {
- uppMyProcInfo = kPascalStackBased
- };
-
- unsigned long __procinfo = uppMyProcInfo;
-
- typedef struct {
- TMTask task;
- Ptr mainBaseAddr;
- Size worldBytes;
- Ptr worldBuffer;
- short rowBytes;
- short phase;
- Rect size;
- short offset;
- } MyTaskRec;
-
- #define kUpdateSpeed 90
-
- typedef struct {
- short numPorts;
- GrafPtr ports [1];
- } **PortListHdl;
-
- int currentPlug = 0;
-
- static bool Bypass ()
- {
- char* t = (char*)0x17b;
- char* t2 = (char*) 0x183;
-
- if(*t2 & 4)
- currentPlug = 0;
- if(*t2 & 1)
- currentPlug = 1;
-
- t2 = (char *) 0x180;
- if(*t2 & 8)
- currentPlug = 2;
- if(*t2 & 1)
- currentPlug = 4;
- if(*t2 & 2)
- currentPlug = 5;
- if(*t2 & 4)
- currentPlug = 6;
- if(*t2 & 16)
- currentPlug = 7;
- if(*t2 & 32)
- currentPlug = 8;
-
- t2 = (char *) 0x182;
- if(*t2 & 0x40)
- currentPlug = 3;
-
-
- if (*t & 2)
- return true;
- else
- return false;
- }
-
- void doWavePlug(MyTaskRec* myTask);
- void doScrollerPlug(MyTaskRec* myTask);
- void doFallingDoorPlug(MyTaskRec* myTask);
- void doKaliedPlug(MyTaskRec* myTask);
- void doSlidePlug(MyTaskRec* myTask);
- void doMungePlug(MyTaskRec* myTask);
- void doPixelatorPlug(MyTaskRec* myTask);
- void doInvertPlug(MyTaskRec* myTask);
- void doSnowPlug(MyTaskRec* myTask);
-
-
-
- static
- void ChangeAllPorts (Ptr oldBaseAddr, Ptr newBaseAddr)
- {
- PortListHdl ports = *((PortListHdl*) 0x0000d66);
-
- for (int i = 0; i < (**ports).numPorts; ++i) {
-
- if ((**ports).ports [i] -> portBits.rowBytes & 0xC000) {
-
- CGrafPtr port = (CGrafPtr) ((**ports).ports [i]);
-
- if (GetPixBaseAddr (port -> portPixMap) == oldBaseAddr)
- (**(port -> portPixMap)).baseAddr = newBaseAddr;
-
- } else {
-
- GrafPtr port = ((**ports).ports [i]);
-
- if (port -> portBits.baseAddr == oldBaseAddr)
- port -> portBits.baseAddr = newBaseAddr;
-
- }
- }
- }
-
- static
- pascal void SimpleBlit (MyTaskRec* myTask)
- {
- short height = myTask -> size.bottom - myTask -> size.top;
- short phase = myTask -> phase;
- short rowBytes = myTask -> rowBytes;
- Ptr worldBuffer = myTask -> worldBuffer;
- Ptr screenBuffer = myTask -> mainBaseAddr;
-
- BlockMoveDataUncached (worldBuffer, screenBuffer, height * rowBytes);
- }
-
- static void FancyBlit (MyTaskRec* myTask)
- {
- short height = myTask -> size.bottom - myTask -> size.top;
- short phase = myTask -> phase;
- short rowBytes = myTask -> rowBytes;
- Ptr worldBuffer = myTask -> worldBuffer;
- Ptr screenBuffer = myTask -> mainBaseAddr;
-
- BlockMoveDataUncached (worldBuffer + phase * rowBytes, screenBuffer, (height - phase) * rowBytes);
- BlockMoveDataUncached (worldBuffer, screenBuffer + (height - phase) * rowBytes, phase * rowBytes);
-
- phase += myTask -> offset;
- if (phase >= height)
- phase = 0;
- else if (phase < 0)
- phase = height;
-
- myTask -> phase = phase;
- }
-
- void doWavePlug(MyTaskRec* myTask);
- void doScrollerPlug(MyTaskRec* myTask);
- void doFallingDoorPlug(MyTaskRec* myTask);
- void doKaliedPlug(MyTaskRec* myTask);
-
- pascal void MyCTimerProc (MyTaskRec* myTask);
-
- /*
- static asm void MyTimerProc ()
- {
- move.l a1, -(sp)
- jsr MyCTimerProc
- rts
- }
- */
-
- typedef struct {
- QDGlobals qd; // Storage for the QuickDraw globals
- long qdGlobalsPtr; // A5 points to this place; it will contain a pointer to qd
- } QDStorage;
-
- MyTaskRec myTask;
-
- static long MySetA5 (void* value)
- {
- short hex [7] = {
- 0x4e56,
- 0x0000,
- 0x202e,
- 0x0008,
- 0xc18d,
- 0x4e5e,
- 0x4e75
- };
-
-
- MakeDataExecutable (&hex, 14);
-
- UniversalProcPtr upp = NewRoutineDescriptor ((ProcPtr) &hex, uppA5Info, kM68kISA);
- if (!upp)
- DebugStr ("\pDONT EVEN THINK ABOUT IT!");
-
- long oldA5 = CallUniversalProc (upp, uppA5Info, value);
-
- return oldA5;
- }
-
- pascal void MyCTimerProc (MyTaskRec* myTask)
- {
- EnterCodeResource ();
- if (Bypass ())
- {
- switch(currentPlug)
- {
- case 0:
- doMungePlug(myTask);
- break;
- case 1:
- FancyBlit (myTask);
- break;
- case 2:
- doInvertPlug(myTask);
- break;
- case 3:
- doScrollerPlug(myTask);
- break;
- case 4:
- doSlidePlug (myTask);
- break;
- case 5:
- doFallingDoorPlug(myTask);
- break;
- case 6:
- doPixelatorPlug(myTask);
- break;
- case 7:
- doKaliedPlug(myTask);
- break;
- case 8:
- doWavePlug(myTask);
- break;
- }
- }
- else
- SimpleBlit (myTask);
-
- ExitCodeResource ();
- PrimeTime ((QElemPtr) myTask, kUpdateSpeed);
- }
-
- static void Override ()
- {
- long oldA5; // Original value of register A5
- QDStorage qds; // Fake QD globals
-
- oldA5 = MySetA5(&qds.qdGlobalsPtr); // Tell A5 to point to the end of the fake QD Globals
- InitGraf(&qds.qd.thePort); // Initialize the fake QD Globals
-
- GDHandle mainDevice = GetMainDevice ();
- PixMapHandle mainPixMap = (**mainDevice).gdPMap;
- Rect mainBounds = (**mainDevice).gdRect;
- short mainRowBytes = (**(**mainDevice).gdPMap).rowBytes;
-
- myTask.mainBaseAddr = (**(**mainDevice).gdPMap).baseAddr;
- myTask.phase = 0;
-
- GWorldPtr world = nil;
-
- Rect tempBounds = mainBounds;
- tempBounds.bottom = tempBounds.top + 1;
-
- if (NewGWorld (&world, (**mainPixMap).pixelSize, &tempBounds, nil, nil, 0))
- goto Exit;
-
- GDHandle device = GetGWorldDevice (world);
- PixMapHandle worldPixMap = GetGWorldPixMap (world);
-
- // GWorld is really short, make a new buffer for it
- Ptr oldWorldBuffer = (**worldPixMap).baseAddr;
- short oldWorldRowBytes = (**worldPixMap).rowBytes;
-
- long bytesNeeded = (mainBounds.bottom - mainBounds.top) * (mainRowBytes & 0x3FFF);
-
- Ptr newWorldBuffer = NewPtrSys (bytesNeeded);
- if (!newWorldBuffer)
- goto Exit;
-
- LockPixels (worldPixMap);
-
- (**worldPixMap).baseAddr = newWorldBuffer;
- (**worldPixMap).rowBytes = mainRowBytes;
- (**worldPixMap).bounds = mainBounds;
-
- LockPixels (mainPixMap);
-
- short worldRowBytes = (**worldPixMap).rowBytes;
- myTask.worldBytes = (mainBounds.bottom - mainBounds.top) * (worldRowBytes & 0x3FFF);
- myTask.worldBuffer = GetPixBaseAddr (worldPixMap);
- myTask.rowBytes = worldRowBytes & 0x3FFF;
- myTask.size = mainBounds;
-
- *((Ptr*)crsrBase) = myTask.worldBuffer;
-
- (**(**mainDevice).gdPMap).baseAddr = myTask.worldBuffer;
- GDeviceChanged (mainDevice);
-
- GrafPtr wMgrPort;
- GetWMgrPort (&wMgrPort);
-
- short wMgrRowBytes = wMgrPort -> portBits.rowBytes;
-
- wMgrPort -> portBits.baseAddr = myTask.worldBuffer;
-
- CGrafPtr cwMgrPort;
- GetCWMgrPort (&cwMgrPort);
-
- short cwMgrRowBytes = (**(cwMgrPort -> portPixMap)).rowBytes;
-
- (**cwMgrPort -> portPixMap).baseAddr = myTask.worldBuffer;
-
- LMSetScrnBase (myTask.worldBuffer);
-
- ChangeAllPorts (myTask.mainBaseAddr, myTask.worldBuffer);
-
- BlockMoveDataUncached (myTask.mainBaseAddr, myTask.worldBuffer, myTask.worldBytes);
-
- myTask.task.tmAddr = (TimerUPP) NewTimerProc (MyCTimerProc);
-
- myTask.task.tmCount = 0;
- myTask.task.tmWakeUp = 0;
- myTask.task.tmReserved = 0;
- myTask.offset = -5;
-
- MySetA5((void*)oldA5);
-
- InsXTime ((QElemPtr) &myTask);
- PrimeTime ((QElemPtr) &myTask, 300);
-
- return;
-
- Exit:
- DebugStr ("\pError");
- }
-
- void initWavePlug();
-
- extern "C" {
- pascal
- void main ();
- }
-
- pascal
- void main ()
- {
- EnterCodeResource ();
-
- THz oldZone = GetZone ();
- SetZone (SystemZone ());
-
- Handle me = Get1IndResource ('INIT', 1);
- HLock (me);
-
- if (!me)
- goto Exit;
-
- initWavePlug();
- Override ();
-
- DetachResource (me);
-
-
- Exit:
- SetZone (oldZone);
- ExitCodeResource ();
- }
-
-